package service

import (
	"context"
	"errors"
	"go-api/api/v1/request"
	"go-api/api/v1/response"
	"go-api/internal/model"
	"go-api/internal/repository"
	"go-api/internal/utils/bcrypt"
	"go-api/internal/utils/common"
	"time"
)

// UserService 用户服务接口
type UserService interface {
	Register(req request.RegisterReq) error
	Audit(req request.AuditReq) error
	Login(req request.LoginReq) (*response.LoginRes, error)
}

// userService 用户服务实现
type userService struct {
	ctx context.Context
}

// NewUserService 创建用户服务
func NewUserService(ctx context.Context) UserService {
	return &userService{
		ctx: ctx,
	}
}

// Register 注册用户
func (s *userService) Register(req request.RegisterReq) error {
	if err := req.CheckParam(); err != nil {
		return err
	}

	// 查询用户是否已经存在
	userSvc := repository.NewUserRepository(s.ctx)
	count, users, err := userSvc.FindUserByEPN(repository.FindUserFilter{
		Email: req.Email,
		Phone: req.Phone,
		AuditStatusArr: []model.AuditStatus{
			model.AuditApproved, model.AuditPending,
		},
	})

	if err != nil {
		return err
	}

	if count != 0 || len(users) != 0 {
		return errors.New("邮箱/电话 已经注册或者处于待审核")
	}

	// 创建用户到待审核
	hashPass, err := bcrypt.HashPassWord(req.Password)
	if err != nil {
		return err
	}

	isChild := 2
	if req.Pid != 0 {
		isChild = 1
	}

	// 名字和昵称可以不填，随机生成
	if req.Name == "" {
		req.Name = common.GenerateRandName(common.NameType)
	}

	if req.NickName == "" {
		req.Name = common.GenerateRandName(common.NickNameType)
	}

	user := model.User{
		UserNumber:  common.GetUserNumber(),
		Name:        req.Name,
		NickName:    req.NickName,
		Email:       req.Email,
		PassWord:    hashPass,
		Status:      -1,
		UserType:    2, // 默认普通用户
		Phone:       req.Phone,
		ApplyTime:   time.Now().Unix(),
		AuditStatus: -1,
		Tag:         -1, // 默认无标签
		Pid:         req.Pid,
		IsChild:     int8(isChild),
		Remark:      req.Remark,
	}

	return userSvc.Create(&user)
}

func (s *userService) Audit(req request.AuditReq) error {
	if req.Id == 0 {
		return errors.New("参数错误")
	}

	if req.AuditOp != model.AuditApproved && req.AuditOp != model.AuditReject {
		return errors.New("审核状态错误")
	}

	userSvc := repository.NewUserRepository(s.ctx)
	ok, data, err := userSvc.FindOnyByID(req.Id)
	if err != nil {
		return err
	}

	if !ok {
		return errors.New("record not found")
	}

	if data.AuditStatus != int8(model.AuditPending) {
		return errors.New("记录不是待审核状态")
	}

	// 更新审核数据 -- 审核状态，启用状态，
	err = userSvc.Update(&model.User{
		Id:          data.Id,
		Status:      1,
		AuditStatus: 1,
	})

	return err
}

func (s *userService) Login(req request.LoginReq) (*response.LoginRes, error) {
	if err := req.CheckParam(); err != nil {
		return nil, err
	}

	// 验证用户状态：1
	userSvc := repository.NewUserRepository(s.ctx)
	count, uInfos, err := userSvc.FindUserByEPN(repository.FindUserFilter{
		Email:  req.Name,
		Phone:  req.Name,
		Status: 1,
	})

	if err != nil {
		return nil, err
	}

	if count == 0 || len(uInfos) == 0 {
		return nil, errors.New("用户不存在")
	}

	if uInfos[0].Status != 1 {
		return nil, errors.New("用户非启用状态")
	}

	// 密码是否正确
	if !bcrypt.CheckPassword(req.Password, uInfos[0].PassWord) {
		return nil, errors.New("密码错误！")
	}

	// todo 生成token

	// 更新登陆时间、登陆位置
	err = userSvc.Update(&model.User{
		Id:            uInfos[0].Id,
		LoginTime:     time.Now().Unix(),
		LoginLocation: "",
	})
	if err != nil {
		return nil, err
	}

	// 返回信息

	return nil, nil
}
